﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace YiLe.UI
{
    public partial class DataProvider : Component
    {
        protected bool mDataLoaded;
        private System.Data.OleDb.OleDbDataAdapter mDataAdapter;

        //intended to be set by inheritors. If a class that inherits from
        //DataProvider does not set this property an exception will be thrown
        //filling or updating data
        public System.Data.OleDb.OleDbDataAdapter DataAdapter
        {
            get
            {
                return mDataAdapter;
            }
            set
            {
                if (mDataAdapter != value)
                {
                    if (mDataAdapter != null)
                    {
                        mDataAdapter.RowUpdated -= new System.Data.OleDb.OleDbRowUpdatedEventHandler(mDataAdapter_RowUpdated);
                    }
                    mDataAdapter = value;
                    if (mDataAdapter != null)
                    {
                        mDataAdapter.RowUpdated += new System.Data.OleDb.OleDbRowUpdatedEventHandler(mDataAdapter_RowUpdated);
                    }
                }
            }
        }

        public YiLeSystemData DataSet
        {
            get
            {
                return mDataSet;
            }
        }
        public void Fill()
        {
            if (!mDataLoaded)
            {
                if (FillCore())
                {
                    mDataLoaded = true;
                }
                else
                {
                    throw new Exception("Data was not loaded.");
                }
            }
        }
        protected virtual bool FillCore()
        {
            return false;
        }


        public bool Update()
        {
            if (!mDataLoaded)
            {
                //if data is not loaded there are no changes and you
                //can return true
                return true;
            }
            try
            {
                return UpdateCore();
            }
            catch (Exception exc)
            {
                MessageBox.Show(this.GetExceptionMessage(exc), YiLeSystemApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
        protected virtual bool UpdateCore()
        {
            return false;
        }
        public bool UpdateDataRow(DataRow row)
        {
            try
            {
                if (UpdateDataRowCore(row))
                {
                    if (mDataLoaded)
                    {
                        this.DataSet.Tables[row.Table.TableName].LoadDataRow(row.ItemArray, true);
                    }
                    return true;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(GetExceptionMessage(exc), YiLeSystemApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return false;
        }
        protected virtual bool UpdateDataRowCore(DataRow row)
        {
            return false;
        }
        public bool DeleteDataRow(DataRow row)
        {
            try
            {
                DataRow rowToDelete = null;
                if (mDataLoaded)
                {
                    //find the row in the table using the primary key
                    DataTable table = DataSet.Tables[row.Table.TableName];
                    object[] pkValues = new object[table.PrimaryKey.Length];

                    for (int i = 0; i < pkValues.Length; i++)
                    {
                        pkValues[i] = row[table.PrimaryKey[i].ColumnName];
                    }
                    rowToDelete = table.Rows.Find(pkValues);
                }
                else
                {
                    rowToDelete = row;
                }
                rowToDelete.Delete();
                return this.UpdateDataRowCore(row);
            }
            catch (Exception exc)
            {
                MessageBox.Show(GetExceptionMessage(exc), YiLeSystemApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
        protected virtual bool DeleteDataRowCore(DataRow row)
        {
            return false;
        }
        //inheritors can customize the exception message overriding this function
        protected virtual string GetExceptionMessage(Exception e)
        {
            return e.Message;
        }

        private void mDataAdapter_RowUpdated(object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e)
        {
            OnRowUpdated(e);
        }

        protected virtual void OnRowUpdated(System.Data.OleDb.OleDbRowUpdatedEventArgs e)
        {
            if (e.Status != UpdateStatus.ErrorsOccurred)
            {
                if (e.StatementType != StatementType.Delete)
                {
                    e.Row.AcceptChanges();
                }
            }
            else
            {
                e.Row.RejectChanges();
            }
        }

    }

} //end of root namespace